package encoder;

public class Instruction {

	private int opCode; 
	private String op1; 
	private String op2; 
	private String op3; 
	
	public int getOpCode() {
		return opCode;
	}

	public void setOpCode(int opCode) {
		this.opCode = opCode;
	}
	
	public String getOp1() {
		return op1;
	}

	public void setOp1(String op1) {
		this.op1 = op1;
	}

	public String getOp2() {
		return op2;
	}

	public void setOp2(String op2) {
		this.op2 = op2;
	}

	public String getOp3() {
		return op3;
	}

	public void setOp3(String op3) {
		this.op3 = op3;
	}

	
	public Instruction(int opCode, String op1, String op2, String op3){
		this.opCode = opCode;
		this.op1 = op1;
		this.op2 = op2;
		this.op3 = op3;
	}	
	
	public String toString(){
		switch(this.opCode){
		case InstructionType.EXTERN:
			return (InstructionType.NAME_EXTERN+" _"+this.op1);
			
		case InstructionType.SECTION:
			return (InstructionType.NAME_SECTION+" "+this.op1);
			
		case InstructionType.RET:
			return (InstructionType.NAME_RET);
			
		case InstructionType.VARIAVEL_GLOBAL:
			if(op2.equals("int")|| op2.equals("boolean"))return (this.op1+": "+ InstructionType.TIPO_INT+ " 0");
			else
				if(this.op3!= null)return(this.op1+": "+InstructionType.TIPO_DOUBLE+ " "+this.op3);
				else return(this.op1+": "+InstructionType.TIPO_DOUBLE+ " 0.0");
			
		case InstructionType.INT_FORMAT:
			return ("intFormat: db "+ "\"%d\","+" 10, 0");
			
		case InstructionType.DOUBLE_FORMAT:
			return ("doubleFormat: db "+ "\"%.2f\","+" 10, 0");
		
		case InstructionType.GLOBAL:
			return ("global _"+ this.op1);
		
		case InstructionType.FUNCAO_LABEL:
			if(!this.op1.equals("main"))
				return (this.op1+":");
			else return("_"+InstructionType.WINMAIN+":");
			
		case InstructionType.PUSH:
			return gerarPush();
			
		case InstructionType.PUSH_FLOAT:
			return gerarPushFloat();
			
		case InstructionType.MOV:
			return (InstructionType.NAME_MOV+" "+this.op1+", "+this.op2);
			
		case InstructionType.POP:
			return (gerarPop());
		
		case InstructionType.ADD:
			return (InstructionType.WORD_ADD+" "+this.op1+", "+this.op2);
		
		case InstructionType.SUB:
			return (InstructionType.WORD_SUB+" "+this.op1+", "+this.op2);
		case InstructionType.MULT:
			return (gerarMult());
		case InstructionType.DIV:
			return (gerarDiv());
			
		case InstructionType.POP_FLOAT:
			return (gerarPopFloat());
			
		case InstructionType.ADD_FLOAT:
			return (InstructionType.FADDP+" "+this.op1);
			
		case InstructionType.SUB_FLOAT:
			return (InstructionType.FSUBP+" "+this.op1);
			
		case InstructionType.MULT_FLOAT:
			return (InstructionType.FMULP+" "+this.op1);
			
		case InstructionType.DIV_FLOAT:
			return (InstructionType.FDIVP+" "+this.op1);
			
		case InstructionType.CALL_FUNTION:
			return (InstructionType.CALL+" _"+this.op1);
			
		case InstructionType.JUMP:
			return (InstructionType.JUMP_WORD+ " "+this.op1);
			
		case InstructionType.CMP:
			return (InstructionType.CMP_WORD+" "+this.op1+", "+this.op2);
		case InstructionType.JE:
			return (InstructionType.JEqual+ " "+this.op1);
		case InstructionType.JGE:
			return (InstructionType.JGreaterEqual+ " "+this.op1);
		case InstructionType.JLE:
			return (InstructionType.JLessEqual+ " "+this.op1);
		case InstructionType.JG:
			return (InstructionType.JGreater+ " "+this.op1);
		case InstructionType.JL:
			return (InstructionType.JLess+ " "+this.op1);
		case InstructionType.JNE:
			return (InstructionType.JNEequal+ " "+this.op1);
		
			
		default:
			return (opCode+" "+op1+" "+op2+" "+op3);
		}
		
	}
	private String gerarDiv(){
		if(this.op2 == null || this.op2.equals(""))
			return (InstructionType.WORD_DIV+" "+this.op1);
		else {
			if(this.op3 == null || this.op3.equals("")){
				return (InstructionType.WORD_DIV2operando+" "+this.op1+", "+this.op2);
			}else
				return (InstructionType.WORD_DIV2operando+" "+this.op1+", "+this.op2+", "+this.op3);
		}
			
	}
	private String gerarMult(){
		if(this.op2 == null || this.op2.equals(""))
			return (InstructionType.WORD_MULT+" "+this.op1);
		else {
			if(this.op3 == null || this.op3.equals("")){
				return (InstructionType.WORD_MULT2operando+" "+this.op1+", "+this.op2);
			}else
				return (InstructionType.WORD_MULT2operando+" "+this.op1+", "+this.op2+", "+this.op3);
		}
			
	}
	private String gerarPush(){
		if(this.op1.equals("int")) {
			if(this.op3 == null || this.op3.equals("")){
				return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" "+this.op2+"");
			}else{
				return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" "+"["+this.op2+this.op3+"]");
			}
		}else
			if(this.op1.equals("boolean")){
				if( this.op2.equals("false")){
					return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" 0");
				}else{
					if( this.op2.equals("true"))
						return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" 1");
					else{
						return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" ["+this.op2+"]");
					}
				}
			}
			else if(this.op1.equals("double")){
				if(this.op3 == null || this.op3.equals("")){
					return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" "+this.op2+"");
				}else{
					return (InstructionType.NAME_PUSH+" "+InstructionType.DWORD+" "+"["+this.op2+this.op3+"]");
				}
			}
		return (InstructionType.NAME_PUSH+" "+this.op1);
	}
	private String gerarPop(){
		if(this.op1.equals("int")) {
			if(this.op3 == null || this.op3.equals("")){
				return (InstructionType.WORD_POP+" "+InstructionType.DWORD+" ["+this.op2+"]");
			}else{
				return (InstructionType.WORD_POP+" "+InstructionType.DWORD+" "+"["+this.op2+this.op3+"]");
			}
		}else
			if(this.op1.equals("boolean")){
				if( this.op2.equals("false")){
					return (InstructionType.WORD_POP+" "+InstructionType.DWORD+" 0");
				}else{
					if( this.op2.equals("true"))
						return (InstructionType.WORD_POP+" "+InstructionType.DWORD+" 1");
					else{
						return (InstructionType.WORD_POP+" "+InstructionType.DWORD+" ["+this.op2+"]");
					}
				}
			}	
		return (InstructionType.WORD_POP+" "+this.op1);
	}
	
	private String gerarPushFloat(){
		if(this.op2 == null || this.op2.equals(""))
			return (InstructionType.FLD+" "+InstructionType.QWORD+" ["+this.op1+"]");
		else 
			return (InstructionType.FLD+" "+InstructionType.QWORD+" ["+this.op1+this.op2+"]");
	}
	private String gerarPopFloat(){
		if(this.op2 == null || this.op2.equals(""))
			return (InstructionType.FSTP+" "+InstructionType.QWORD+" ["+this.op1+"]");
		else 
			return (InstructionType.FSTP+" "+InstructionType.QWORD+" ["+this.op1+this.op2+"]");
	}
}
